package com.v2.k23;


import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.*;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.JdkRegexpMethodPointcut;

import java.lang.reflect.Method;

/**
 * 测试Aop2  非注解
 * 测试ProxyFactory
 */
public class Test {

	public static void main(String[] args) {

		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.setTarget(new TestProxyService());

		//前置通知  前置advice
		proxyFactory.addAdvice(new MethodBeforeAdvice() {
			@Override
			public void before(Method method, Object[] args, Object target) throws Throwable {
				System.out.println("前置通知。。。");
			}
		});

		//后置通知  后置advice
		proxyFactory.addAdvice(new AfterReturningAdvice() {
			@Override
			public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
				System.out.println("后置通知（目标函数调用后，出现异常不会调用）。。。");
			}
		});

		//环绕通知  环绕advice
		proxyFactory.addAdvice(new MethodInterceptor() {
			@Override
			public Object invoke(MethodInvocation invocation) throws Throwable {
				System.out.println("环绕通知之前。。。");
				Object obj = invocation.proceed();
				System.out.println("环绕通知之后。。。");
				return obj;
			}
		});

		//异常通知  异常advice
		//不能在运行的方法中直接new ThrowsAdvice然后实现afterThrowing方法，这样因为出异常，线程挂了，也会无法运行这个afterThrowing方法。
		//切点
		JdkRegexpMethodPointcut cut = new JdkRegexpMethodPointcut();
		cut.setPatterns(new String[]{".*fun1.*"});
		Advice advice = new ThrowException();
		//切面 = 切点 + 通知
		Advisor advisor = new DefaultPointcutAdvisor(cut, advice);
		proxyFactory.addAdvisor(advisor);

		TestProxyService testProxyService = (TestProxyService)proxyFactory.getProxy();
		testProxyService.fun1();
	}

}
